package com.dom.invoapp.modular.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.dom.common.constants.ConstantError;
import com.dom.common.enums.CancelStatEnum;
import com.dom.common.enums.PubStatEnum;
import com.dom.common.enums.PurcOrderStatEnum;
import com.dom.common.enums.VerfyStatEnum;
import com.dom.common.exception.ServiceException;
import com.dom.common.model.vo.apply.OrderDetailInfo;
import com.dom.common.model.vo.apply.P030R;
import com.dom.common.model.vo.apply.P032R;
import com.dom.common.model.vo.apply.P039R;
import com.dom.common.utils.BeanUtil;
import com.dom.invoapp.dao.entity.TpPurcOrderDetailFlow;
import com.dom.invoapp.dao.entity.TpPurcOrderFlow;
import com.dom.invoapp.dao.service.ITTradeDateService;
import com.dom.invoapp.dao.service.ITpPurcOrderDetailFlowService;
import com.dom.invoapp.dao.service.ITpPurcOrderFlowService;
import com.xiaoleilu.hutool.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class PurcOrderService {
    @Autowired
    private ITpPurcOrderFlowService purcOrderFlowService;
    @Autowired
    private ITpPurcOrderDetailFlowService purcOrderDetailFlowService;
    @Autowired
    private ITTradeDateService tradeDateService;

    public String insertPurcOrder(P030R request) {
        TpPurcOrderFlow orderFlow = new TpPurcOrderFlow();
        BeanUtils.copyProperties(request, orderFlow);
        orderFlow.setOrganCode(request.getOrgId());
        orderFlow.setDocuMakerId(request.getOperId());
        orderFlow.setAbbrName(request.getSuppAbbrName());
        orderFlow.setStat(PurcOrderStatEnum.ORDER_STAT_WAITING.getCode());
        orderFlow.setVerfyStat(VerfyStatEnum.VERFY_STAT_CONFIRMING.getCode());
        orderFlow.setCancelStat(CancelStatEnum.CANCEL_STAT_NORMAL.getCode());
        orderFlow.setDeliDate(DateUtil.parse(request.getDeliDate(), "yyyy-MM-dd"));
        orderFlow.setExchDate(tradeDateService.getExchDate(0));

        boolean result = purcOrderFlowService.insert(orderFlow);
        if (!result) {
            log.info("登记采购订单失败, result:{}", result);
            throw new ServiceException(ConstantError.DATAERROR);
        }

        /**
         * 遍历采购单，登记采购订单明细记录
         */
        List<TpPurcOrderDetailFlow> orderDetailFlows = new ArrayList<>();
        request.getOrderDetailData().forEach(item -> {
            orderDetailFlows.add(convertEntity(item, orderFlow));
        });
        boolean batchResult = purcOrderDetailFlowService.insertBatch(orderDetailFlows);
        if(!batchResult){
            log.info("录入采购订单明细失败, result:{}", batchResult);
            throw new ServiceException(ConstantError.DATAERROR);
        }
        return orderFlow.getId().toString();
    }

    /**
     * 将orderDetailInfo对象转换为采购订单明细实体对象
     *
     * @param info
     * @return
     */
    public TpPurcOrderDetailFlow convertEntity(OrderDetailInfo info, TpPurcOrderFlow orderFlow) {
        TpPurcOrderDetailFlow entity = new TpPurcOrderDetailFlow();
        entity.setMemCode(orderFlow.getMemCode());
        entity.setOrderId(orderFlow.getId());
        entity.setGoodCode(info.getGoodCode());
        entity.setGoodName(info.getGoodName());
        entity.setVarietyCode(info.getVarietyCode());
        entity.setVarietyName(info.getVarietyName());
        entity.setStandardName(info.getStandardName());
        entity.setUnit(info.getUnit());
        entity.setInTaxRate(info.getInTaxRate());

        info.setPrice(info.getPrice() == null ? BigDecimal.valueOf(0) : info.getPrice());
        entity.setPrice(info.getPrice());
        entity.setNoTaxPrice(info.getNoTaxPrice());
        entity.setAmount(info.getAmount());
        entity.setRemAmount(info.getAmount());
        //计算总金额
        info.setAmount(info.getAmount() == null ? BigDecimal.valueOf(0) : info.getAmount());
        BigDecimal bal = info.getPrice().multiply(info.getAmount()).setScale(2, BigDecimal.ROUND_HALF_UP);
        entity.setBal(info.getPrice().multiply(info.getAmount()));

        //计算预估进项税
        BigDecimal estInTax = info.getPrice().multiply(info.getAmount()).multiply(info.getInTaxRate()).setScale(2, BigDecimal.ROUND_HALF_UP);
        entity.setNoTaxBal(bal.subtract(estInTax));
        entity.setEstInTax(estInTax);
        entity.setDigest(info.getDigest());
        entity.setStat(PurcOrderStatEnum.ORDER_STAT_WAITING.getCode());
        return entity;
    }

    public Page findByPage(P039R p039R) {
        Page<TpPurcOrderFlow> page = new Page<>();
        page.setSize(p039R.getPs() == 0 ? 20 : p039R.getPs());
        page.setCurrent(p039R.getPn());

        Wrapper wrapper = new EntityWrapper();
        wrapper.between("exch_date", DateUtil.parse(p039R.getExchStartDate(), "yyyy-MM-dd"), DateUtil.parse(p039R.getExchEndDate(), "yyyy-MM-dd"))
                .and().between("deli_date", DateUtil.parse(p039R.getDeliStartDate(), "yyyy-MM-dd"), DateUtil.parse(p039R.getDeliEndDate(), "yyyy-MM-dd"));
        if (!StringUtils.isEmpty(p039R.getStat())) {
            wrapper.and().eq("stat", p039R.getStat());
        }

        if (StringUtils.isNotEmpty(p039R.getMakerId())) {
            wrapper.and().eq("docu_maker_id", p039R.getMakerId());
        }
        List<String> orderList = new ArrayList<>();
        orderList.add("exch_date");
        orderList.add("make_date");
        wrapper.orderBy(true, orderList, false);
        return purcOrderFlowService.selectPage(page, wrapper);
    }

    public List<TpPurcOrderDetailFlow> findPurcOrderDetailList(Integer memCode, Integer orderId) {
        Wrapper<TpPurcOrderDetailFlow> wrapper = new EntityWrapper<>();
        wrapper.eq("mem_code", memCode)
                .and().eq("order_id", orderId)
                .and().eq("stat", PubStatEnum.STAT_NORMAL.getCode())
                .orderBy("id", false);
        return purcOrderDetailFlowService.selectList(wrapper);
    }

    public TpPurcOrderFlow selectPurcOrderInfo(Integer memCode, Integer orderId){
//        Wrapper<TpPurcOrderFlow> wrapper = new EntityWrapper<>();
//        wrapper.eq("mem_code", memCode)
//                .and().eq("id", orderId);
//        return purcOrderFlowService.selectOne(wrapper);
        return purcOrderFlowService.selectById(orderId);
    }

    public TpPurcOrderFlow editPurcOrderInfo(P032R request){
        TpPurcOrderFlow orderFlow = selectPurcOrderInfo(request.getMemCode(), request.getOrderId());
        BeanUtil.copyPropertiesIgnoreNull(request, orderFlow);

        boolean result = purcOrderFlowService.updateById(orderFlow);
        return orderFlow;
    }

    public boolean editPurcOrderDetail(Integer memCode, Integer orderId, List<TpPurcOrderDetailFlow> purcOrderDetailFlows){
        Wrapper<TpPurcOrderDetailFlow> wrapper = new EntityWrapper<>();
        wrapper.eq("mem_code", memCode)
                .and().eq("order_id", orderId);
        List<TpPurcOrderDetailFlow> origFlows = purcOrderDetailFlowService.selectList(wrapper);
        origFlows.forEach(origFlow ->{
            origFlow.setStat(PubStatEnum.STAT_STOP.getCode());
        });
        boolean result = purcOrderDetailFlowService.updateBatchById(origFlows);

        return purcOrderDetailFlowService.insertBatch(purcOrderDetailFlows);
    }
}
